package com.payment.ktb.utils;

import android.text.TextUtils;
import android.util.Base64;

import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.payment.ktb.Interface.HttpCallbackListener;
import com.payment.ktb.RespException;
import com.payment.ktb.application.MyApplication;
import com.payment.ktb.constants.Constants;
import com.payment.ktb.constants.ConstantsActionLoginState;
import com.payment.ktb.constants.ConstantsUser;

import org.json.JSONException;
import org.json.JSONObject;

import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

/**
 * Created by syd on 2015/12/15.
 * 说明：这是封装的一个Vollery的工具类。接收Map类型的输入参数，再将这个Map转换成JSON作为post的数据。
 *
 */
public class HttpUtils {



    public static void HttpRequestByVollery(String url, final String action, final Map<String,String> postData, RequestQueue mQueue, final HttpCallbackListener listener) {

        StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
                @Override
                public void onResponse(String responseString) {
                    String respData = null;
                    //LogUtil.e("responseString=" + responseString);
                    try {
                        if (Arrays.asList(ConstantsActionLoginState.ACTIONUNLOGINANDLOGIN).contains(action)) {
                            if (!TextUtils.isEmpty(SharedPreferencesUtils.getString(ConstantsUser.userToken))) {
                                //登陆后请求网络
                                respData = decodeResponseParameterLogin(responseString);
                            }else {
                                //未登录请求网络
                                respData = decodeResponseParameterUnLogin(responseString);
                            }
                        } else if ( Arrays.asList(ConstantsActionLoginState.ACTIONUNLOGIN).contains(action)) {
                            //未登录请求网络
                            respData = decodeResponseParameterUnLogin(responseString);
                        }else {
                            //登陆后请求网络
                            respData = decodeResponseParameterLogin(responseString);
                        }
                    } catch (JSONException e) {

                        JSONObject jsonResponseMsg = null;
                        try {
                            jsonResponseMsg = new JSONObject(responseString);
                        } catch (JSONException e1) {

                            VolleyError volleyError = new VolleyError(responseString);
                            listener.onError(volleyError);
                            return;
                        }
//                        String respDate = new String(Base64.decode(AESUtils.decode(jsonResponseMsg.optString("data"),SharedPreferencesUtils.getString(ConstantsUser.userKey).substring(0,16)),Base64.DEFAULT));
//                        JSONObject jsonRespDate = new JSONObject(respDate);


                        VolleyError volleyError = new VolleyError("" + jsonResponseMsg);
                        listener.onError(volleyError);
                        return;



//
//                        e.printStackTrace();
//                        VolleyError volleyError = new VolleyError("JSON解析异常");
//                        listener.onError(volleyError);
//                        return;
                    } catch (RespException e) {
                        e.printStackTrace();
                        VolleyError volleyError = new VolleyError(e.getMessage());
                        listener.onError(volleyError);
                        return;
                    } catch (Exception e) {
                        e.printStackTrace();
                        VolleyError volleyError = new VolleyError("AES解密错误！");
                        listener.onError(volleyError);
                        return;
                    }
                    listener.onFinish(respData);
                }
            },new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                LogUtil.e("volleyError=" + volleyError.getMessage());
                VolleyError volleyErrorResp = new VolleyError("网络已断开，请连接网络");
                listener.onError(volleyErrorResp);
            }
        }){
                @Override
                protected Map<String, String> getParams() throws AuthFailureError {

                    LogUtil.e("postData=" + postData);
                    LogUtil.e("postAction=" + action);

                    //ServiceInfoList这个接口，商户登录的时候，用登录的token
                    //没登录的话，用默认的token

                    if (Arrays.asList(ConstantsActionLoginState.ACTIONUNLOGINANDLOGIN).contains(action)) {
                        if (!TextUtils.isEmpty(SharedPreferencesUtils.getString(ConstantsUser.userToken))) {
                            //登陆后请求网络
                            return createRequestParameterLogin(action,postData);
                        }else {
                            //未登录请求网络
                            return createRequestParameterUnLogin(action,postData);
                        }
                    } else if ( Arrays.asList(ConstantsActionLoginState.ACTIONUNLOGIN).contains(action)) {
                        //未登录请求网络
                       return createRequestParameterUnLogin(action,postData);
                    }else {
                        //登陆后请求网络
                        return createRequestParameterLogin(action,postData);
                    }
                }
            };

        //修改vollery请求超时时间为8s
        stringRequest.setRetryPolicy(new DefaultRetryPolicy(15000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));


        //mQueue.add(stringRequest);
        MyApplication.getInstance().getRequestQueue().add(stringRequest);
    }












    public static Map<String,String> createRequestParameterUnLogin(String action,Map<String,String> requestMap) {
        String token = Constants.TOKEN;
        String key = Constants.KEY;
        String unAESPostData = new JSONObject(requestMap).toString();
        String Base64postData = Base64.encodeToString(unAESPostData.getBytes(), Base64.DEFAULT);
        String AESPostData = null;
        try {
            AESPostData = AESUtils.encode(Base64postData, key.substring(0,16));
        } catch (Exception e) {
            e.printStackTrace();
        }

        HashMap<String,String> returnMap = new HashMap<String,String>();
        //sign=Md5(action+token+data+授权蜜钥)
        String sign = Md5Utils.md5Hex(action + token + AESPostData + key);
        returnMap.put("sign", URLEncoder.encode(sign));
        returnMap.put("token",URLEncoder.encode(token));
        returnMap.put("data", URLEncoder.encode(AESPostData));
        returnMap.put("action",URLEncoder.encode(action));
        return returnMap;
    }



    public static Map<String,String> createRequestParameterLogin(String action,Map<String,String> requestMap) {
        String token = SharedPreferencesUtils.getString(ConstantsUser.userToken);
        String key = SharedPreferencesUtils.getString(ConstantsUser.userKey);
        String unAESPostData = new JSONObject(requestMap).toString();
        String Base64postData = Base64.encodeToString(unAESPostData.getBytes(), Base64.DEFAULT);
        String AESPostData = null;
        try {
            AESPostData = AESUtils.encode(Base64postData, key.substring(0,16));
        } catch (Exception e) {
            e.printStackTrace();
        }

        HashMap<String,String> returnMap = new HashMap<String,String>();
        //sign=Md5(action+token+data+授权蜜钥)
        String sign = Md5Utils.md5Hex(action + token + AESPostData + key);
        returnMap.put("sign", URLEncoder.encode(sign));
        returnMap.put("token",URLEncoder.encode(token));
        returnMap.put("data", URLEncoder.encode(AESPostData));
        returnMap.put("action",URLEncoder.encode(action));
        return returnMap;
    }



    private static String decodeResponseParameterUnLogin(String responseMsg) throws JSONException, RespException, IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException, NoSuchAlgorithmException, InvalidKeyException {

        JSONObject jsonResponseMsg = new JSONObject(responseMsg);
        String respCode = jsonResponseMsg.optString(Constants.RESPCODE);
        if (!respCode.equals("200")) {
            throw new RespException(jsonResponseMsg.optString(Constants.RESPMSG));
        }
        String respDate = new String(Base64.decode(AESUtils.decode(jsonResponseMsg.optString("data"),Constants.KEY.substring(0,16)),Base64.DEFAULT));
        LogUtil.e("respDate=" + respDate);
        JSONObject jsonRespDate = new JSONObject(respDate);
        if (!jsonRespDate.optString(Constants.CODE).equals(Constants.NORMAL_CODE)) {
            throw new RespException(jsonRespDate.optString(Constants.MSG));
        }
        return respDate;
    }




    private static String decodeResponseParameterLogin(String responseMsg) throws JSONException, RespException, IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException, NoSuchAlgorithmException, InvalidKeyException {

        JSONObject jsonResponseMsg = new JSONObject(responseMsg);
        String respCode = jsonResponseMsg.optString(Constants.RESPCODE);
        if (!respCode.equals("200")) {
            throw new RespException(jsonResponseMsg.optString(Constants.RESPMSG));
        }
        String respDate = new String(Base64.decode(AESUtils.decode(jsonResponseMsg.optString("data"),SharedPreferencesUtils.getString(ConstantsUser.userKey).substring(0,16)),Base64.DEFAULT));
        LogUtil.e("respDate=" + respDate);
        JSONObject jsonRespDate = new JSONObject(respDate);
        if (!jsonRespDate.optString(Constants.CODE).equals(Constants.NORMAL_CODE)) {
            throw new RespException(jsonRespDate.optString(Constants.MSG));
        }
        return respDate;
    }



}
